From 723d57eeb51b1f0977d30c3b6a8ad3533747daa8 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 21 Apr 2020 12:05:45 -0400 Subject: [PATCH] widget: Add a system_setting_changed vfunc This gives us a hook to walk the widget tree whenever a global setting changes and do per-widget invalidations. This will replace gtk_style_context_reset_widgets(). --- docs/reference/gtk/gtk4-sections.txt | 1 + gtk/gtkenums.h | 29 +++++++++++++++++++ gtk/gtkwidget.c | 43 ++++++++++++++++++++++++++++ gtk/gtkwidget.h | 4 +++ gtk/gtkwidgetprivate.h | 4 +++ 5 files changed, 81 insertions(+) diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt index 2f65276175..7d3ba28659 100644 --- a/docs/reference/gtk/gtk4-sections.txt +++ b/docs/reference/gtk/gtk4-sections.txt @@ -2312,6 +2312,7 @@ GtkSettingsValue gtk_settings_get_default gtk_settings_get_for_display gtk_settings_reset_property +GtkSystemSetting GtkSettingsClass GTK_IS_SETTINGS diff --git a/gtk/gtkenums.h b/gtk/gtkenums.h index 3069183f61..d7611f0f36 100644 --- a/gtk/gtkenums.h +++ b/gtk/gtkenums.h @@ -1088,4 +1088,33 @@ typedef enum { GTK_CONSTRAINT_VFL_PARSER_ERROR_INVALID_RELATION } GtkConstraintVflParserError; +/** + * GtkSystemSetting: + * @GTK_SYSTEM_SETTING_DPI: the #GtkSettings:gtk-xft-dpi setting has changed + * @GTK_SYSTEM_SETTING_FONT_NAME: The #GtkSettings:gtk-font-name setting has changed + * @GTK_SYSTEM_SETTING_FONT_CONFIG: The font configuration has changed in a way that + * requires text to be redrawn. This can be any of the + * #GtkSettings:gtk-xft-antialias, #GtkSettings:gtk-xft-hinting, + * #GtkSettings:gtk-xft-hintstyle, #GtkSettings:gtk-xft-rgba or + * #GtkSettings:gtk-fontconfig-timestamp settings + * @GTK_SYSTEM_SETTING_DISPLAY: The display has changed + * @GTK_SYSTEM_SETTING_ICON_THEME: The icon theme has changed in a way that requires + * icons to be looked up again + * + * Values that can be passed to the GtkWidgetClass.system_setting_changed + * vfunc to indicate that a system setting has changed and widgets may + * need to drop caches, or react otherwise. + * + * Most of the values correspond to #GtkSettings properties. + * + * More values may be added over time. + */ +typedef enum { + GTK_SYSTEM_SETTING_DPI, + GTK_SYSTEM_SETTING_FONT_NAME, + GTK_SYSTEM_SETTING_FONT_CONFIG, + GTK_SYSTEM_SETTING_DISPLAY, + GTK_SYSTEM_SETTING_ICON_THEME +} GtkSystemSetting; + #endif /* __GTK_ENUMS_H__ */ diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 6486b18da5..8d8d3d366b 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -592,6 +592,8 @@ static gboolean gtk_widget_real_query_tooltip (GtkWidget *widget, GtkTooltip *tooltip); static void gtk_widget_real_css_changed (GtkWidget *widget, GtkCssStyleChange *change); +static void gtk_widget_real_system_setting_changed (GtkWidget *widget, + GtkSystemSetting setting); static void gtk_widget_real_set_focus_child (GtkWidget *widget, GtkWidget *child); @@ -911,6 +913,7 @@ gtk_widget_class_init (GtkWidgetClass *klass) klass->keynav_failed = gtk_widget_real_keynav_failed; klass->query_tooltip = gtk_widget_real_query_tooltip; klass->css_changed = gtk_widget_real_css_changed; + klass->system_setting_changed = gtk_widget_real_system_setting_changed; /* Accessibility support */ klass->priv->accessible_type = GTK_TYPE_ACCESSIBLE; @@ -4865,6 +4868,20 @@ gtk_widget_real_css_changed (GtkWidget *widget, } } +static void +gtk_widget_real_system_setting_changed (GtkWidget *widget, + GtkSystemSetting setting) +{ + GtkWidget *child; + + for (child = _gtk_widget_get_first_child (widget); + child != NULL; + child = _gtk_widget_get_next_sibling (child)) + { + gtk_widget_system_setting_changed (child, setting); + } +} + static gboolean direction_is_forward (GtkDirectionType direction) { @@ -10627,6 +10644,32 @@ gtk_widget_css_changed (GtkWidget *widget, GTK_WIDGET_GET_CLASS (widget)->css_changed (widget, change); } +void +gtk_widget_system_setting_changed (GtkWidget *widget, + GtkSystemSetting setting) +{ + GTK_WIDGET_GET_CLASS (widget)->system_setting_changed (widget, setting); +} + +void +gtk_system_setting_changed (GdkDisplay *display, + GtkSystemSetting setting) +{ + GList *list, *toplevels; + + toplevels = gtk_window_list_toplevels (); + g_list_foreach (toplevels, (GFunc) g_object_ref, NULL); + + for (list = toplevels; list; list = list->next) + { + if (gtk_widget_get_display (list->data) == display) + gtk_widget_system_setting_changed (list->data, setting); + g_object_unref (list->data); + } + + g_list_free (toplevels); +} + GtkCssNode * gtk_widget_get_css_node (GtkWidget *widget) { diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h index a08309efb8..021a96c604 100644 --- a/gtk/gtkwidget.h +++ b/gtk/gtkwidget.h @@ -201,6 +201,7 @@ struct _GtkWidget * should then discard their caches that depend on CSS and queue resizes or * redraws accordingly. The default implementation will take care of this for * all the default CSS properties, so implementations must chain up. + * @system_setting_changed: Emitted when a system setting was changed. Must chain up. * @snapshot: Vfunc for gtk_widget_snapshot(). * @contains: Vfunc for gtk_widget_contains(). */ @@ -277,6 +278,9 @@ struct _GtkWidgetClass void (* css_changed) (GtkWidget *widget, GtkCssStyleChange *change); + void (* system_setting_changed) (GtkWidget *widget, + GtkSystemSetting settings); + void (* snapshot) (GtkWidget *widget, GtkSnapshot *snapshot); diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h index db969f4cb2..b0d851d272 100644 --- a/gtk/gtkwidgetprivate.h +++ b/gtk/gtkwidgetprivate.h @@ -282,6 +282,10 @@ gboolean _gtk_widget_captured_event (GtkWidget *widget, void gtk_widget_css_changed (GtkWidget *widget, GtkCssStyleChange *change); +void gtk_widget_system_setting_changed (GtkWidget *widget, + GtkSystemSetting setting); +void gtk_system_setting_changed (GdkDisplay *display, + GtkSystemSetting setting); void _gtk_widget_update_parent_muxer (GtkWidget *widget); GtkActionMuxer * _gtk_widget_get_action_muxer (GtkWidget *widget, -- 2.30.2